home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLUT / progs / examples / triselect.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  9KB  |  420 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /**
  5.  * (c) Copyright 1993, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40.  
  41. #include <stdio.h>
  42. #include <stdlib.h>
  43. #include <math.h>
  44. #include <string.h>
  45. #include <time.h>
  46. #include <GL/glut.h>
  47.  
  48. #define MAXOBJS 10000
  49. #define MAXSELECT 100
  50. #define MAXFEED 300
  51. #define    SOLID 1
  52. #define    LINE 2
  53. #define    POINT 3
  54.  
  55. GLint windW = 300, windH = 300;
  56.  
  57. GLuint selectBuf[MAXSELECT];
  58. GLfloat feedBuf[MAXFEED];
  59. GLint vp[4];
  60. float zRotation = 90.0;
  61. float zoom = 1.0;
  62. GLint objectCount;
  63. GLint numObjects;
  64. struct object {
  65.   float v1[2];
  66.   float v2[2];
  67.   float v3[2];
  68.   float color[3];
  69. } objects[MAXOBJS];
  70. GLenum linePoly = GL_FALSE;
  71.  
  72. static void 
  73. InitObjects(GLint num)
  74. {
  75.   GLint i;
  76.   float x, y;
  77.  
  78.   if (num > MAXOBJS) {
  79.     num = MAXOBJS;
  80.   }
  81.   if (num < 1) {
  82.     num = 1;
  83.   }
  84.   objectCount = num;
  85.  
  86.   srand((unsigned int) time(NULL));
  87.   for (i = 0; i < num; i++) {
  88.     x = (rand() % 300) - 150;
  89.     y = (rand() % 300) - 150;
  90.  
  91.     objects[i].v1[0] = x + (rand() % 50) - 25;
  92.     objects[i].v2[0] = x + (rand() % 50) - 25;
  93.     objects[i].v3[0] = x + (rand() % 50) - 25;
  94.     objects[i].v1[1] = y + (rand() % 50) - 25;
  95.     objects[i].v2[1] = y + (rand() % 50) - 25;
  96.     objects[i].v3[1] = y + (rand() % 50) - 25;
  97.     objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  98.     objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  99.     objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  100.   }
  101. }
  102.  
  103. static void 
  104. Init(void)
  105. {
  106.   numObjects = 10;
  107.   InitObjects(numObjects);
  108. }
  109.  
  110. static void 
  111. Reshape(int width, int height)
  112. {
  113.   windW = width;
  114.   windH = height;
  115.   glViewport(0, 0, windW, windH);
  116.   glGetIntegerv(GL_VIEWPORT, vp);
  117. }
  118.  
  119. static void 
  120. Render(GLenum mode)
  121. {
  122.   GLint i;
  123.  
  124.   for (i = 0; i < objectCount; i++) {
  125.     if (mode == GL_SELECT) {
  126.       glLoadName(i);
  127.     }
  128.     glColor3fv(objects[i].color);
  129.     glBegin(GL_POLYGON);
  130.     glVertex2fv(objects[i].v1);
  131.     glVertex2fv(objects[i].v2);
  132.     glVertex2fv(objects[i].v3);
  133.     glEnd();
  134.   }
  135. }
  136.  
  137. static GLint 
  138. DoSelect(GLint x, GLint y)
  139. {
  140.   GLint hits;
  141.  
  142.   glSelectBuffer(MAXSELECT, selectBuf);
  143.   glRenderMode(GL_SELECT);
  144.   glInitNames();
  145.   glPushName(~0);
  146.  
  147.   glPushMatrix();
  148.  
  149.   glMatrixMode(GL_PROJECTION);
  150.   glLoadIdentity();
  151.   gluPickMatrix(x, windH - y, 4, 4, vp);
  152.   gluOrtho2D(-175, 175, -175, 175);
  153.   glMatrixMode(GL_MODELVIEW);
  154.  
  155.   glClearColor(0.0, 0.0, 0.0, 0.0);
  156.   glClear(GL_COLOR_BUFFER_BIT);
  157.  
  158.   glScalef(zoom, zoom, zoom);
  159.   glRotatef(zRotation, 0, 0, 1);
  160.  
  161.   Render(GL_SELECT);
  162.  
  163.   glPopMatrix();
  164.  
  165.   hits = glRenderMode(GL_RENDER);
  166.   if (hits <= 0) {
  167.     return -1;
  168.   }
  169.   return selectBuf[(hits - 1) * 4 + 3];
  170. }
  171.  
  172. static void 
  173. RecolorTri(GLint h)
  174. {
  175.   objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  176.   objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  177.   objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  178. }
  179.  
  180. static void 
  181. DeleteTri(GLint h)
  182. {
  183.   objects[h] = objects[objectCount - 1];
  184.   objectCount--;
  185. }
  186.  
  187. static void 
  188. GrowTri(GLint h)
  189. {
  190.   float v[2];
  191.   float *oldV;
  192.   GLint i;
  193.  
  194.   v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  195.   v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  196.   v[0] /= 3;
  197.   v[1] /= 3;
  198.  
  199.   for (i = 0; i < 3; i++) {
  200.     switch (i) {
  201.     case 0:
  202.       oldV = objects[h].v1;
  203.       break;
  204.     case 1:
  205.       oldV = objects[h].v2;
  206.       break;
  207.     case 2:
  208.       oldV = objects[h].v3;
  209.       break;
  210.     }
  211.     oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  212.     oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  213.   }
  214. }
  215.  
  216. static void 
  217. Mouse(int button, int state, int mouseX, int mouseY)
  218. {
  219.   GLint hit;
  220.  
  221.   if (state == GLUT_DOWN) {
  222.     hit = DoSelect((GLint) mouseX, (GLint) mouseY);
  223.     if (hit != -1) {
  224.       if (button == GLUT_LEFT_BUTTON) {
  225.         RecolorTri(hit);
  226.       } else if (button == GLUT_MIDDLE_BUTTON) {
  227.         GrowTri(hit);
  228.       } else if (button == GLUT_RIGHT_BUTTON) {
  229.         DeleteTri(hit);
  230.       }
  231.       glutPostRedisplay();
  232.     }
  233.   }
  234. }
  235.  
  236. static void 
  237. Draw(void)
  238. {
  239.   glPushMatrix();
  240.   glMatrixMode(GL_PROJECTION);
  241.   glLoadIdentity();
  242.   gluOrtho2D(-175, 175, -175, 175);
  243.   glMatrixMode(GL_MODELVIEW);
  244.   glClearColor(0.0, 0.0, 0.0, 0.0);
  245.   glClear(GL_COLOR_BUFFER_BIT);
  246.   glScalef(zoom, zoom, zoom);
  247.   glRotatef(zRotation, 0, 0, 1);
  248.   Render(GL_RENDER);
  249.   glPopMatrix();
  250.   glutSwapBuffers();
  251. }
  252.  
  253. static void 
  254. DumpFeedbackVert(GLint * i, GLint n)
  255. {
  256.   GLint index;
  257.  
  258.   index = *i;
  259.   if (index + 7 > n) {
  260.     *i = n;
  261.     printf("  ???\n");
  262.     return;
  263.   }
  264.   printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  265.     feedBuf[index],
  266.     feedBuf[index + 1],
  267.     feedBuf[index + 2],
  268.     feedBuf[index + 3],
  269.     feedBuf[index + 4],
  270.     feedBuf[index + 5]);
  271.   index += 7;
  272.   *i = index;
  273. }
  274.  
  275. static void 
  276. DrawFeedback(GLint n)
  277. {
  278.   GLint i;
  279.   GLint verts;
  280.  
  281.   printf("Feedback results (%d floats):\n", n);
  282.   for (i = 0; i < n; i++) {
  283.     switch ((GLint) feedBuf[i]) {
  284.     case GL_POLYGON_TOKEN:
  285.       printf("Polygon");
  286.       i++;
  287.       if (i < n) {
  288.         verts = (GLint) feedBuf[i];
  289.         i++;
  290.         printf(": %d vertices", verts);
  291.       } else {
  292.         verts = 0;
  293.       }
  294.       printf("\n");
  295.       while (verts) {
  296.         DumpFeedbackVert(&i, n);
  297.         verts--;
  298.       }
  299.       i--;
  300.       break;
  301.     case GL_LINE_TOKEN:
  302.       printf("Line:\n");
  303.       i++;
  304.       DumpFeedbackVert(&i, n);
  305.       DumpFeedbackVert(&i, n);
  306.       i--;
  307.       break;
  308.     case GL_LINE_RESET_TOKEN:
  309.       printf("Line Reset:\n");
  310.       i++;
  311.       DumpFeedbackVert(&i, n);
  312.       DumpFeedbackVert(&i, n);
  313.       i--;
  314.       break;
  315.     default:
  316.       printf("%9.2f\n", feedBuf[i]);
  317.       break;
  318.     }
  319.   }
  320.   if (i == MAXFEED) {
  321.     printf("...\n");
  322.   }
  323.   printf("\n");
  324. }
  325.  
  326. static void 
  327. DoFeedback(void)
  328. {
  329.   GLint x;
  330.  
  331.   glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  332.   (void) glRenderMode(GL_FEEDBACK);
  333.  
  334.   glPushMatrix();
  335.  
  336.   glMatrixMode(GL_PROJECTION);
  337.   glLoadIdentity();
  338.   gluOrtho2D(-175, 175, -175, 175);
  339.   glMatrixMode(GL_MODELVIEW);
  340.  
  341.   glClearColor(0.0, 0.0, 0.0, 0.0);
  342.   glClear(GL_COLOR_BUFFER_BIT);
  343.  
  344.   glScalef(zoom, zoom, zoom);
  345.   glRotatef(zRotation, 0, 0, 1);
  346.  
  347.   Render(GL_FEEDBACK);
  348.  
  349.   glPopMatrix();
  350.  
  351.   x = glRenderMode(GL_RENDER);
  352.   if (x == -1) {
  353.     x = MAXFEED;
  354.   }
  355.   DrawFeedback((GLint) x);
  356. }
  357.  
  358. static void 
  359. Key(unsigned char key, int x, int y)
  360. {
  361.  
  362.   switch (key) {
  363.   case 'z':
  364.     zoom /= 0.75;
  365.     glutPostRedisplay();
  366.     break;
  367.   case 'Z':
  368.     zoom *= 0.75;
  369.     glutPostRedisplay();
  370.     break;
  371.   case 'f':
  372.     DoFeedback();
  373.     glutPostRedisplay();
  374.     break;
  375.   case 'l':
  376.     linePoly = !linePoly;
  377.     if (linePoly) {
  378.       glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  379.     } else {
  380.       glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  381.     }
  382.     glutPostRedisplay();
  383.     break;
  384.   case 27:
  385.     exit(0);
  386.   }
  387. }
  388.  
  389. static void 
  390. SpecialKey(int key, int x, int y)
  391. {
  392.  
  393.   switch (key) {
  394.   case GLUT_KEY_LEFT:
  395.     zRotation += 0.5;
  396.     glutPostRedisplay();
  397.     break;
  398.   case GLUT_KEY_RIGHT:
  399.     zRotation -= 0.5;
  400.     glutPostRedisplay();
  401.     break;
  402.   }
  403. }
  404.  
  405. int 
  406. main(int argc, char **argv)
  407. {
  408.   glutInit(&argc, argv);
  409.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  410.   glutCreateWindow("Select Test");
  411.   Init();
  412.   glutReshapeFunc(Reshape);
  413.   glutKeyboardFunc(Key);
  414.   glutSpecialFunc(SpecialKey);
  415.   glutMouseFunc(Mouse);
  416.   glutDisplayFunc(Draw);
  417.   glutMainLoop();
  418.   return 0;             /* ANSI C requires main to return int. */
  419. }
  420.